<template>
  <div class="fulink-fly-box" :ref="refName">
    <svg :width="width" :height="height">
      <defs>
        <path
            :id="pathId"
            :d="path"
            fill="none"
        />
        <radialGradient
            :id="radialGradientId"
            r="50%"
            fx="100%"
            fy="50%"
            cx="50%"
            cy="50%"
        >
          <stop offset="0%" stop-color="white" stop-opacity="1"/>
          <stop offset="100%" stop-color="white" stop-opacity="0"/>
        </radialGradient>
        <mask :id="maskId">
          <circle
              :r="starLength"
              cx="0"
              cy="0"
              :fill="`url(#${radialGradientId})`">
            <animateMotion
                :path="path"
                :dur="`${duration}s`"
                rotate="auto"
                repeatCount="indefinite"
            />
          </circle>
        </mask>
      </defs>
      <use
          :href="`#${pathId}`"
          :stroke="lineColor"
          stroke-width="1"
      />
      <use
          :href="`#${pathId}`"
          :stroke="starColor"
          stroke-width="3"
          :mask="`url(#${maskId})`"
      />
    </svg>
    <div class="fulink-fly-box-content">
      <slot></slot>
    </div>
  </div>
</template>

<script>
import {computed, ref, onMounted, getCurrentInstance} from 'vue'
import {v4 as uuidv4} from 'uuid'

export default {
  name: "FulinkFlyBox",
  props: {
    lineColor: {
      type: String,
      default: '#235fa7'
    },
    starColor: {
      type: String,
      default: '#4fd2dd'
    },
    starLength: {
      type: [Number, String],
      default: 50
    },
    duration: {
      type: [Number, String],
      default: 3
    }
  },
  setup() {
    const uuid = uuidv4()
    const width = ref(0)
    const height = ref(0)
    const refName = 'fulinkFylBox'
    const pathId = `${refName}-path-${uuid}`
    const radialGradientId = `${refName}-gradient-${uuid}`
    const maskId = `${refName}-mask-${uuid}`
    const path = computed(() =>
        `M5 5 L${width.value - 5} 5 L${width.value - 5} ${height.value - 5} L5 ${height.value - 5} Z`
    )

    const init = () => {
      const instance = getCurrentInstance()
      const dom = instance.ctx.$refs[refName]
      width.value = dom.clientWidth
      height.value = dom.clientHeight
    }

    onMounted(() => {
      init()
    })

    return {
      width,
      height,
      path,
      refName,
      pathId,
      radialGradientId,
      maskId
    }
  }
}
</script>

<style lang="scss" scoped>
.fulink-fly-box {
  position: relative;
  width: 100%;
  height: 100%;

  svg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }

  .fulink-fly-box-content {
    width: 100%;
    height: 100%;
    padding: 5px;
    box-sizing: border-box;
  }
}
</style>
